from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import password_validation
from .models import User, Role, Menu, Permission


class CustomUserCreationForm(UserCreationForm):
    """
    自定义用户创建表单
    """
    nickname = forms.CharField(max_length=64, required=False, label='昵称')
    phone = forms.CharField(max_length=20, required=False, label='电话')
    email = forms.EmailField(required=False, label='邮箱')
    roles = forms.ModelMultipleChoiceField(
        queryset=Role.objects.all(),
        widget=forms.CheckboxSelectMultiple,
        required=False,
        label='角色'
    )

    class Meta:
        model = User
        fields = ('username', 'nickname', 'email', 'phone', 'roles', 'password1', 'password2')


class UserUpdateForm(forms.ModelForm):
    """
    用户更新表单
    """
    class Meta:
        model = User
        fields = ('username', 'nickname', 'email', 'phone', 'is_active', 'roles')
        labels = {
            'username': '用户名',
            'nickname': '昵称',
            'email': '邮箱',
            'phone': '电话',
            'is_active': '是否启用',
            'roles': '角色',
        }
        widgets = {
            'roles': forms.CheckboxSelectMultiple(),
        }


class UserUpdateWithPasswordForm(forms.ModelForm):
    """
    用户更新表单（包含密码修改）
    """
    password1 = forms.CharField(
        label='新密码',
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
        strip=False,
        help_text=password_validation.password_validators_help_text_html(),
        required=False
    )
    password2 = forms.CharField(
        label='确认新密码',
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
        strip=False,
        required=False,
        help_text='再次输入新密码'
    )

    class Meta:
        model = User
        fields = ('username', 'nickname', 'email', 'phone')
        labels = {
            'username': '用户名',
            'nickname': '昵称',
            'email': '邮箱',
            'phone': '电话',
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 如果是更新用户，密码字段不是必需的
        self.fields['password1'].required = False
        self.fields['password2'].required = False

    def clean_password2(self):
        # 检查两次输入的密码是否一致
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 or password2:
            if password1 != password2:
                raise forms.ValidationError("两次输入的密码不一致")
            password_validation.validate_password(password2, self.instance)
        return password2

    def clean_username(self):
        # 检查用户名是否唯一（排除当前用户）
        username = self.cleaned_data.get("username")
        if username and User.objects.filter(username=username).exclude(pk=self.instance.pk).exists():
            raise forms.ValidationError("该用户名已被使用")
        return username

    def save(self, commit=True):
        user = super().save(commit=False)
        password = self.cleaned_data.get("password1")
        if password:
            user.set_password(password)
        if commit:
            user.save()
        return user


class AdminUserUpdateForm(forms.ModelForm):
    """
    管理员用户更新表单（包含密码修改）
    """
    password1 = forms.CharField(
        label='新密码',
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
        strip=False,
        help_text=password_validation.password_validators_help_text_html(),
        required=False
    )
    password2 = forms.CharField(
        label='确认新密码',
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
        strip=False,
        required=False,
        help_text='再次输入新密码'
    )

    class Meta:
        model = User
        fields = ('username', 'nickname', 'email', 'phone', 'is_active', 'roles')
        labels = {
            'username': '用户名',
            'nickname': '昵称',
            'email': '邮箱',
            'phone': '电话',
            'is_active': '是否启用',
            'roles': '角色',
        }
        widgets = {
            'roles': forms.CheckboxSelectMultiple(),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 如果是更新用户，密码字段不是必需的
        self.fields['password1'].required = False
        self.fields['password2'].required = False

    def clean_password2(self):
        # 检查两次输入的密码是否一致
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 or password2:
            if password1 != password2:
                raise forms.ValidationError("两次输入的密码不一致")
            password_validation.validate_password(password2, self.instance)
        return password2

    def clean_username(self):
        # 检查用户名是否唯一（排除当前用户）
        username = self.cleaned_data.get("username")
        if username and User.objects.filter(username=username).exclude(pk=self.instance.pk).exists():
            raise forms.ValidationError("该用户名已被使用")
        return username

    def save(self, commit=True):
        user = super().save(commit=False)
        password = self.cleaned_data.get("password1")
        if password:
            user.set_password(password)
        if commit:
            user.save()
        return user


class RoleForm(forms.ModelForm):
    """
    角色表单
    """
    class Meta:
        model = Role
        fields = ('name', 'description', 'permissions', 'menus')
        labels = {
            'name': '角色名称',
            'description': '描述',
            'permissions': '权限',
            'menus': '菜单',
        }
        widgets = {
            'description': forms.Textarea(attrs={'rows': 3}),
            'permissions': forms.CheckboxSelectMultiple(),
            'menus': forms.CheckboxSelectMultiple(),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 按应用名称对权限进行分组
        permissions = Permission.objects.all()
        grouped_permissions = {}
        
        for perm in permissions:
            # 从url_name中提取应用名称
            if ':' in perm.url_name:
                app_name = perm.url_name.split(':')[0]
            else:
                app_name = '通用'
                
            if app_name not in grouped_permissions:
                grouped_permissions[app_name] = []
            grouped_permissions[app_name].append(perm)
        
        # 重新组织权限选项
        permission_choices = []
        for app_name, perms in grouped_permissions.items():
            permission_choices.append((app_name, [(perm.id, perm.name) for perm in perms]))
        
        self.fields['permissions'].choices = permission_choices


class MenuForm(forms.ModelForm):
    """
    菜单表单
    """
    class Meta:
        model = Menu
        fields = ('name', 'url', 'icon', 'parent', 'order', 'is_active')
        labels = {
            'name': '菜单名称',
            'url': 'URL',
            'icon': '图标',
            'parent': '父菜单',
            'order': '排序',
            'is_active': '是否启用',
        }
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 优化父菜单选项显示，按层级展示
        menus = Menu.objects.all().order_by('order')
        menu_choices = [('', '---------')]
        
        # 按层级组织菜单选项
        def add_menu_options(menus, parent=None, level=0):
            prefix = "--" * level
            for menu in menus.filter(parent=parent).order_by('order'):
                menu_label = f"{prefix} {menu.name}"
                if menu.get_level() == 0:
                    menu_label += " (应用)"
                menu_choices.append((menu.id, menu_label))
                # 递归添加子菜单
                add_menu_options(menus, menu, level + 1)
        
        add_menu_options(menus)
        
        self.fields['parent'].choices = menu_choices
        self.fields['parent'].widget.attrs.update({'class': 'form-control'})